package com.agilespirit.presentation.components.application.wizard;

import java.util.Arrays;

import org.apache.wicket.ajax.AjaxEventBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.EnumChoiceRenderer;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.form.RequiredTextField;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.StringResourceModel;

import com.agilespirit.application.ApplicationServiceImpl;
import com.agilespirit.domain.Application;
import com.agilespirit.domain.Country;
import com.agilespirit.domain.Environment;
import com.agilespirit.domain.Platform;
import com.agilespirit.presentation.pages.application.list.ApplicationListPage;

public abstract class ApplicationWizard extends Panel {

  private static final long serialVersionUID = 4907116541209734919L;

  /* Components */
  Form<Application> form;
  RequiredTextField<String> nameInput;
  DropDownChoice<Environment> environmentInput;
  DropDownChoice<Platform> platformInput;
  DropDownChoice<Country> countryInput;
  RequiredTextField<String> hostInput;
  RequiredTextField<Integer> portInput;
  RequiredTextField<String> usernameInput;
  PasswordTextField passwordInput;

  /* Model data*/
  IModel<Application> model;

  public ApplicationWizard(String id, IModel<Application> model) {
    super(id);
    this.model = model;
    buildForm();
  }

  protected abstract boolean isCreationMode();

  private void buildForm() {
    form = new Form<Application>("form");
    form.setOutputMarkupId(true);

    buildTitle();
    buildGeneralSection();
    buildServerSection();
    buildButtonBar();

    add(form);
  }

  protected abstract String getTitleKey();

  private void buildTitle() {
    Label title = new Label("title", new StringResourceModel(getTitleKey(), ApplicationWizard.this, null));
    form.add(title);
  }

  private void buildGeneralSection() {
    buildNameInput();
    buildEnvironmentInput();
    buildPlatformInput();
    buildCountryInput();
  }

  private void buildNameInput() {
    nameInput = new RequiredTextField<String>("name");
    add(nameInput);
  }

  private void buildEnvironmentInput() {
    environmentInput = new DropDownChoice<Environment>("environment", Arrays.asList(Environment.values()),
        new EnumChoiceRenderer<Environment>(this));
    add(environmentInput);
  }

  private void buildPlatformInput() {
    platformInput = new DropDownChoice<Platform>("platform", Arrays.asList(Platform.values()),
        new EnumChoiceRenderer<Platform>(this));
    add(platformInput);
  }

  private void buildCountryInput() {
    countryInput = new DropDownChoice<Country>("country", Arrays.asList(Country.values()),
        new EnumChoiceRenderer<Country>(this));
    add(countryInput);
  }

  private void buildServerSection() {
    buildHostInput();
    buildPortInput();
    buildUsernameInput();
    buildPasswordInput();
  }

  private void buildHostInput() {
    hostInput = new RequiredTextField<String>("host");
    add(hostInput);
  }

  private void buildPortInput() {
    portInput = new RequiredTextField<Integer>("port");
    add(portInput);
  }

  private void buildUsernameInput() {
    usernameInput = new RequiredTextField<String>("username");
    add(usernameInput);
  }

  private void buildPasswordInput() {
    passwordInput = new PasswordTextField("password");
    add(passwordInput);
  }

  private void buildButtonBar() {
    buildResetButton();
    buildValidateButton();
  }

  private void buildResetButton() {
    Button resetButton = new Button("resetButton");
    resetButton.add(new AjaxEventBehavior("onClick") {
      private static final long serialVersionUID = 1L;

      @Override
      protected void onEvent(AjaxRequestTarget target) {
        nameInput.clearInput();
        environmentInput.clearInput();
        platformInput.clearInput();
        countryInput.clearInput();
        hostInput.clearInput();
        portInput.clearInput();
        usernameInput.clearInput();
        passwordInput.clearInput();
        target.add(form);
      }

    });
    form.add(resetButton);
  }

  private void buildValidateButton() {
    AjaxButton validateButton = new AjaxButton("validateButton") {
      private static final long serialVersionUID = 1L;

      @Override
      protected void onError(AjaxRequestTarget target, Form<?> form) {
        target.add(form);
      }

      @Override
      protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
        ApplicationServiceImpl.getInstance().saveOrUpdate(model.getObject());
        setResponsePage(ApplicationListPage.class);
      }

    };
    validateButton.setModel(new StringResourceModel(getValidateButtonKey(), ApplicationWizard.this, null));
    form.add(validateButton);
  }

  protected abstract String getValidateButtonKey();

}
